package com.wuditp.smile.core.domain;

import java.util.List;
import java.util.Vector;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.FetchType;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.MappedSuperclass;
import javax.persistence.OneToMany;

/**
 * 树型对象基类
 * 
 * @author kevin.tao
 * 
 */
@MappedSuperclass
public class DomainTreeNode extends DomainInstance implements TreeNodeable, UnDeletable {

	private static final long serialVersionUID = 1L;

	@Column(name = "is_deleted")
	protected Boolean isDeleted = Boolean.FALSE;

	@ManyToOne(fetch = FetchType.LAZY)
	@JoinColumn(name = "parent_id")
	protected TreeNodeable parent;

	@OneToMany(fetch = FetchType.LAZY, cascade = { CascadeType.ALL })
	@JoinColumn(name = "parent_id")
	protected List<TreeNodeable> childrens;

	@Override
	public <T extends TreeNodeable> void addChildren(T entry) {
		if (null == entry) {
			return;
		}
		if (null == this.childrens) {
			this.childrens = new Vector<TreeNodeable>();
		}
		if (!this.childrens.contains(entry)) {
			this.childrens.add(entry);
			entry.setParent(this);
		}
	}

	@Override
	public <T extends TreeNodeable> void setChildrens(List<T> childrens) {
		if (null != childrens && !childrens.isEmpty()) {
			for (T entry : childrens) {
				this.addChildren(entry);
			}
		}
	}

	@Override
	public <T extends TreeNodeable> void removeChildren(T entry) {
		if (null == this.childrens || null == entry) {
			return;
		}
		if (this.childrens.contains(entry)) {
			this.childrens.remove(entry);
			entry.setParent(null);
		}
	}

	@Override
	public List<? extends TreeNodeable> getChildrens() {
		return this.childrens;
	}

	@Override
	public TreeNodeable getParent() {
		return this.parent;
	}

	@Override
	public <T extends TreeNodeable> void setParent(T parent) {
		this.parent = parent;
	}

	@Override
	public boolean isBranch() {
		return !this.isLeaf();
	}

	@Override
	public boolean isLeaf() {
		return null == this.childrens || this.childrens.isEmpty();
	}

	@Override
	public boolean isRoot() {
		return TreeNodeable.ROOT.equals(this.getId());
	}

	@Override
	public boolean isDeleted() {
		return null == this.isDeleted ? false : this.isDeleted.booleanValue();
	}

	@Override
	public void markedAsAvailable() {
		this.isDeleted = Boolean.TRUE;
	}

	@Override
	public void markedAsDeleted() {
		this.isDeleted = Boolean.FALSE;
	}

	public Boolean getIsDeleted() {
		return isDeleted;
	}

	public void setIsDeleted(Boolean isDeleted) {
		this.isDeleted = isDeleted;
	}

}
